package com.xbongbong.saas.service.impl;

import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.health.pojo.dto.GetByDateDTO;
import com.xbongbong.pro.health.pojo.dto.LineChartDTO;
import com.xbongbong.pro.health.pojo.vo.GetByDateVO;
import com.xbongbong.pro.health.pojo.vo.LineChartVO;
import com.xbongbong.saas.domain.entity.DayHealthEntity;
import com.xbongbong.saas.model.DayHealthModel;
import com.xbongbong.saas.service.HealthService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author chy
 * @time 2019-02-22 13:34
 */
@Service("healthService")
public class HealthServiceImpl implements HealthService {

    private static final Logger LOG = LoggerFactory.getLogger(HealthServiceImpl.class);

    @Resource
    private DayHealthModel dayHealthModel;

    /**
     * 2019-02-21 到 2019-02-24 最大的健康度为69，预估系统中最大的健康度在70左右  1000/70 约等于 14
     */
    private final Float modulus = 14F;

    /**
     * 预估的health上限
     */
    private final Float UPPER_LIMIT = 1000f;

    @Override
    public GetByDateVO getByDate(GetByDateDTO getByDateDTO) throws XbbException {
        GetByDateVO getByDateVO = new GetByDateVO();
        String date = getByDateDTO.getDate();
        Long dateInt = null;

        try {
            dateInt = DateTimeUtil.getInt(date, DateUtil.SDFDate);
        } catch (Exception e) {
            dateInt = DateTimeUtil.getInt();
        }

        String corpid = getByDateDTO.getCorpid();
        DayHealthEntity dayHealth = dayHealthModel.getEntityByEntryDate(corpid, dateInt);

        Float health = 0F;
        if (dayHealth != null) {
            health = dayHealth.getHealthDegree();
        }

        Long yesterdayInt = dateInt - TimeConstant.SECONDS_PER_DAY;
        DayHealthEntity yesterdayDayHealth = dayHealthModel.getEntityByEntryDate(corpid, yesterdayInt);

        Float yesterdayHealth = 0F;
        if (yesterdayDayHealth != null) {
            yesterdayHealth = yesterdayDayHealth.getHealthDegree();
        }

        getByDateVO.setHealth(health * modulus);
        Float difference = (health - yesterdayHealth) * modulus;
        getByDateVO.setDifference(difference);
        getByDateVO.setUpperLimit(UPPER_LIMIT);
        return getByDateVO;
    }

    @Override
    public LineChartVO lineChart(LineChartDTO lineChartDTO) throws XbbException {
        String corpid = lineChartDTO.getCorpid();
        String startDate = lineChartDTO.getStartDate();
        String endDate = lineChartDTO.getEndDate();

        Integer startDateInt = null;
        Integer endDateInt = null;

        try {
            startDateInt = DateUtil.getInt(startDate, DateUtil.SDFDate);
            endDateInt = DateUtil.getInt(endDate, DateUtil.SDFDate);
        } catch (Exception e) {
            LOG.error("lineChart 中时间格式转换错误", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100029, SystemErrorCodeEnum.API_ERROR_100029.getMsg());
        }

        LineChartVO lineChartVO = new LineChartVO();
        List<String> xAxis = getXAxis(startDateInt, endDateInt);
        List<Float> data = getData(corpid, startDateInt, endDateInt, xAxis);
        xAxis = formatDateTime(xAxis);
        lineChartVO.setXAxis(xAxis);
        lineChartVO.setData(data);
        return lineChartVO;
    }

    /**
     * 将yyyy-MM-dd格式的时间转换成MM-dd
     * @param xAxis 年月日时间集合
     * @return
     */
    private List<String> formatDateTime(List<String> xAxis) {
        List<String> retList = new ArrayList<>();
        for (String x : xAxis) {
            Long timeInt = DateTimeUtil.getInt(x, DateTimeUtil.SDFDate);
            retList.add(DateTimeUtil.getStringEpochSecond(timeInt, DateTimeUtil.SDFMonthDay));
        }
        return retList;
    }

    /**
     * 获取横坐标对应的纵坐标的值
     * @param corpid 公司
     * @param startDateInt 开始时间
     * @param endDateInt 结束时间
     * @param xAxis 横坐标
     * @return
     * 创建时间 2019/2/25 8:27 PM
     * 修改时间 2019/2/25 8:27 PM
     * @author chy
     * @since v1.0
     * @version v1.0
     */
    private List<Float> getData(String corpid, Integer startDateInt, Integer endDateInt, List<String> xAxis) {
        List<DayHealthEntity> dayHealthList = dayHealthModel.getListByTime(corpid, startDateInt, endDateInt);
        Map<String, Float> dayHealthMap = new HashMap<>(8);

        for(DayHealthEntity dayHealthEntity : dayHealthList){
            String dateStr = DateTimeUtil.getDateStringEpochSecond(dayHealthEntity.getEntryDate());
            Float health = dayHealthEntity.getHealthDegree() * modulus;
            dayHealthMap.put(dateStr, health);
        }

        List<Float> data = new ArrayList<>();
        for(String x : xAxis){
            Float y = dayHealthMap.get(x);
            y = y == null ? 0F : y;
            data.add(y);
        }
        return data;
    }

    /**
     * 通过时间获取横坐标
     * @param startDateInt
     * @param endDateInt
     * @return
     * 创建时间 2019/2/25 8:05 PM
     * 修改时间 2019/2/25 8:05 PM
     * @author chy
     * @since v1.0
     * @version v1.0
     */
    private List<String> getXAxis(Integer startDateInt, Integer endDateInt) {
        List<String> xAxis = new ArrayList<>();

        Integer oneDay = 86400;

        for(int i = 0; endDateInt >= startDateInt + i * oneDay; i++){
            Integer nowDateInt = startDateInt + i * oneDay;
            xAxis.add(DateUtil.getString(nowDateInt, DateUtil.SDFDate));
        }
        return xAxis;
    }
}
